package test.my.com.myapplicationtest.BI_view;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.DecelerateInterpolator;

import java.text.DecimalFormat;

import test.my.com.myapplicationtest.R;

/**
 * Author : Cooper
 * Time : 2017/9/14  14:10
 * Description : 动态圆圈统计View
 */
public class DynaYHstlView extends View {

    private Context mContext;

    private int mWidth = 100;
    private int mHeight = 100;
    private int START_ANGLE = 160; // 起始角度
    private int SWEEP_ANGLE = 220; // 旋转角度

    private int mArcStlColor; // 圆弧颜色
    private int mDefaultArcStlColor = Color.parseColor("#F0F0F0"); // 默认圆弧颜色
    private int mArcStlStrokeWidth = 20; // 圆弧宽度

    private int mStlTextColor; // 文字颜色

    private int mStlValueSize = 30; // 数值文字大小
    private int mStlTitleSize = 20; // 标题文字大小

    private int mStartAngle; // 圆弧起始角度
    private int mAnimatorTime; // 圆弧动画时间
    private RectF mRectF;
    private int mSpace = 30; // 圆弧偏移（解决边缘显示不全）

    private Paint mBgPaint;
    private Paint mPointPaint;
    private Paint mArtPaint;
    private Paint mValuePaint;
    private Paint mTitlePaint;

    private float mPointX; // 圆弧端点显示圆点的坐标
    private float mPonitY;

    private float mCenterX; // 圆弧中心坐标
    private float mCenterY;

    private Rect mValueRect = new Rect();// 用于获取文字宽高
    private Rect mTitleRect = new Rect();// 用于获取文字宽高
    private float mValue;
    private String mTitle = "";
    private float mDynamicAngle;;// 动态圆弧画的角度
    private ValueAnimator valueAnimator;
    private ValueAnimator mArcAnimator;
    private DecimalFormat mValueFormat;

    public DynaYHstlView(Context context) {
        super(context);
    }

    public DynaYHstlView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DynaYHstlView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.DynaYHstlView, defStyleAttr, 0);
        mArcStlColor = ta.getColor(R.styleable.DynaYHstlView_arcStlColor, Color.BLUE);
        mStlTextColor = ta.getColor(R.styleable.DynaYHstlView_arcStlTextColor, Color.parseColor("#78849A"));
        mAnimatorTime = ta.getInt(R.styleable.DynaYHstlView_animatorStlTime, 1000);
        ta.recycle();

        init(context);
    }

    private void init(Context context) {
        this.mContext = context;
        mBgPaint = new Paint();
        mBgPaint.setStrokeWidth(mArcStlStrokeWidth);
        mBgPaint.setColor(mDefaultArcStlColor);
        mBgPaint.setStrokeCap(Paint.Cap.ROUND);
        mBgPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        mBgPaint.setStyle(Paint.Style.STROKE);

        mArtPaint = new Paint();
        mArtPaint.setStrokeWidth(mArcStlStrokeWidth);
        mArtPaint.setColor(mArcStlColor);
        mArtPaint.setStrokeCap(Paint.Cap.ROUND);
        mArtPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        mArtPaint.setStyle(Paint.Style.STROKE);

        mPointPaint = new Paint();
        mPointPaint.setColor(Color.WHITE);
        mPointPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        mPointPaint.setStyle(Paint.Style.FILL);

        mValuePaint = new Paint();
        mValuePaint.setColor(mStlTextColor);
        mValuePaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        mValuePaint.setTextSize(mStlValueSize);
        mValuePaint.setTypeface(Typeface.createFromAsset(context.getAssets(), "DINMittelschrift-Alternate.otf"));

        mTitlePaint = new Paint();
        mTitlePaint.setColor(mStlTextColor);
        mTitlePaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        mTitlePaint.setTextSize(mStlTitleSize);

        mValueFormat = new DecimalFormat(".00");
    }

    public void setValue(float value ,String title) {
        float sweepAngle = value * SWEEP_ANGLE / 100;
        this.mTitle = title;
        setAnimator(value,sweepAngle);
    }

    private void setAnimator(final float value,float sweepAngle) {
        mArcAnimator = ValueAnimator.ofFloat(0, sweepAngle);
        mArcAnimator.setDuration(mAnimatorTime);
        mArcAnimator.setInterpolator(new DecelerateInterpolator());
        mArcAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mDynamicAngle = (float) valueAnimator.getAnimatedValue();
                invalidate();
            }
        });
        mArcAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                if (mDynamicAngle == 0) {
                    mDynamicAngle = 0.01f;
                }
                invalidate();
            }
        });
        mArcAnimator.start();

        valueAnimator = ValueAnimator.ofFloat(0, value);
        valueAnimator.setDuration(mAnimatorTime);
        valueAnimator.setInterpolator(new DecelerateInterpolator());
        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                mValue = value;
                invalidate();
            }
        });
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mValue =(float) valueAnimator.getAnimatedValue();
                invalidate();
            }
        });
        valueAnimator.start();
    }

    /**
     * 计算圆弧端点显示圆点的坐标
     */
    private void caculateLocaltionXY() {
        mCenterX = mRectF.width() / 2+mSpace;
        mCenterY = mRectF.height() / 2+mSpace;
        float radius = mRectF.width() / 2;

        mPointX =  mCenterX + (float)(radius * Math.cos((START_ANGLE + mDynamicAngle) * Math.PI / 180));
        mPonitY =  mCenterY + (float)(radius * Math.sin((START_ANGLE + mDynamicAngle) * Math.PI / 180));
    }

    /**
     * 计算弧形宽度、数值size、标题size
     */
    private void caculateViewSize() {
        mStlValueSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mRectF.width()/12,
                getResources().getDisplayMetrics());
        mStlTitleSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mRectF.width()/23,
                getResources().getDisplayMetrics());
        mArcStlStrokeWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mRectF.width()/25,
                getResources().getDisplayMetrics());

        mTitlePaint.setTextSize(mStlTitleSize);
        mValuePaint.setTextSize(mStlValueSize);
        mArtPaint.setStrokeWidth(mArcStlStrokeWidth);
        mBgPaint.setStrokeWidth(mArcStlStrokeWidth);

        mValuePaint.getTextBounds(mValueFormat.format(mValue)+"%",0,(mValueFormat.format(mValue)+"%").length(),mValueRect);
        mTitlePaint.getTextBounds(mTitle,0,mTitle.length(),mTitleRect);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        caculateViewSize();
        caculateLocaltionXY();
        canvas.drawArc(mRectF, START_ANGLE, SWEEP_ANGLE, false, mBgPaint);
        canvas.drawArc(mRectF, START_ANGLE, mDynamicAngle, false, mArtPaint);
        canvas.drawCircle(mPointX, mPonitY, mArcStlStrokeWidth / 3, mPointPaint);
        canvas.drawText(mValueFormat.format(mValue)+"%",mCenterX-mValueRect.width()/2,mCenterY+mValueRect.height()/2,mValuePaint);
        canvas.drawText(mTitle,mCenterX-mTitleRect.width()/2,mRectF.bottom,mTitlePaint);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
        mRectF = new RectF(mSpace, mSpace, mWidth - mSpace, mHeight - mSpace);
    }

    private int measureWidth(int widthMeasureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(widthMeasureSpec);
        int specSize = MeasureSpec.getSize(widthMeasureSpec);
        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            result = mWidth;
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        this.mWidth = result;
        return result;
    }

    private int measureHeight(int heightMeasureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(heightMeasureSpec);
        int specSize = MeasureSpec.getSize(heightMeasureSpec);
        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            result = mHeight;
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        this.mHeight = result;
        return result;
    }


}
